package v2

import (
	"net/http"

	"gitee.com/lipore/plume/logger"
	"github.com/gin-gonic/gin"
)

type Code struct {
	code       int
	httpStatus int
}

func NewCode(code int, httpStatus int) *Code {
	return &Code{
		code:       code,
		httpStatus: httpStatus,
	}
}

func ResponseError(c *gin.Context, err error) {
	NewErrorResponse().WithError(err).WriteResponse(c)
}

func ErrorHandleMiddleware() gin.HandlerFunc {
	return func(c *gin.Context) {
		defer func() {
			if err := recover(); err != nil {
				logger.Errorf("handle request with error: %v", err)
				if err, ok := err.(error); ok {
					logger.Errorf("%v", err)
					ResponseError(c, err)
				}
				c.AbortWithStatus(http.StatusInternalServerError)
			}
		}()
		c.Next()
	}
}

// swagger:response errorResponse
type ErrorResponse struct {
	HttpStatus int

	err error
	// in: body
	Payload struct {
		// error code
		Code int `json:"code"`
		// error message
		Message string `json:"message"`
	} `json:"body"`
}

func NewErrorResponse() *ErrorResponse {
	return &ErrorResponse{}
}

func (r *ErrorResponse) WithError(err error) *ErrorResponse {
	if err == nil {
		return r
	}
	r.err = err
	r.HttpStatus = http.StatusInternalServerError
	r.Payload.Code = 0
	r.Payload.Message = err.Error()
	return r
}

func (r *ErrorResponse) WriteResponse(ctx *gin.Context) {
	logger.Warnf("response error, http status: %d, response: %v", r.HttpStatus, r.Payload)
	logger.Debugf("response error, error: %+v", r.err)
	ctx.Header(Status, Error)
	ctx.JSON(r.HttpStatus, r.Payload)
}
